Skip to content

test(cli): widen the scaffold-comment pin to both scaffolders - #15151

Merged
os-trump merged 1 commit into
mainfrom
claude/issue-14823-create-template-comments-pin
Sep 4, 2026
Merged

test(cli): widen the scaffold-comment pin to both scaffolders#15151
os-trump merged 1 commit into
mainfrom
claude/issue-14823-create-template-comments-pin

Conversation

@os-trump

@os-trump os-trump commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Fixes #14823

packages/cli/test/init-template-comments-self-contained.test.ts rendered its population from exactly one source — TEMPLATES from init.js — so its three assertions held for os init only. packages/cli/src/commands/create.ts exports a second, independent template map whose entries render text straight into a scaffolded project, and nothing read it.

The population is now derived from both maps, the way scaffold-manifest-schema.test.ts derives its own sweep, so a template added to either map is swept the day it is added. The three assertions are reused unchanged; only their labels now name the scaffold arm (init:app, create:example) so a failure says which command ships the text.

The sequencing fence is released

Triage ruled "Sequence after #14821" because the two-source precedent did not exist on main. It does now — packages/cli/test/scaffold-manifest-schema.test.ts is present at origin/main e37456eb03, and this change follows its shape.

Derived, not inherited: what the three assertions say about create's current text

The card's "self-contained today" sentence described #14821's branch. Run against main's actual create template text, all three assertions pass. The widened pin is green on the unmodified tree — 25 tests, over 15 rendered files across 5 scaffold arms (3 init + 2 create).

So there is nothing for this PR to report as caught, and no follow-up card falls out of a red. Assertion 2 in particular now covers create:example's protocol-range comment (the one #14821 added), and assertion 3 checks its https://objectstack.ai/docs/upgrading link against content/docs/upgrading.mdx, which is present.

What the create half sweeps

create has no configContent / srcFiles split — one files map keyed by destination path, rendered by calling the entry. Every entry is rendered and serialised exactly the way Create.run() does it (a string verbatim, anything else through JSON.stringify(_, null, 2)). Sweeping the whole map rather than a chosen subset is deliberate: a filter is a place a future file can escape through silently, which is the shape of the defect being closed. This picks up the plugin template's src/index.ts and README.md literals, as the card asked — a pin covering only example would recreate the card one template over.

The create vacuity guard checks its in-source literals were reached rather than requiring an objectstack.config.ts, which its plugin template deliberately does not emit.

Proof — red-first, with the arm named

One ablation run, both legs, trap-guarded restore on absolute paths. Both legs mutate source the pin imports relatively (../src/commands/*.js resolving to packages/cli/src/commands/*.ts), so vite reads the mutated source directly — there is no dist hop, and the reddening itself is the proof the mutation reached the code under test.

The injection is a synthetic monorepo-only reference (// Rationale: ADR-0999, see #12345) added after the shared anchor line in each file.

leg mutation on disk pin exit failures
baseline, unmodified 0 Tests 25 passed (25)
arm under testcreate.ts blob 779e4fec to 723cd4ba, marker count 1 1 1 failedcreate:example/objectstack.config.ts cites nothing that only exists in this monorepo
positive controlinit.ts blob 26565625 to 02386b79, marker count 3 1 3 failedinit:app, init:plugin, init:empty objectstack.config.ts

The harness discriminates: the create injection reddens exactly one create arm and no init arm; the init injection reddens exactly the three init arms and no create arm. The failure message carries the arm and the marker:

create:example/objectstack.config.ts cites an ADR identifier ("ADR-0999"). A project
scaffolded by `os create` ships no ADRs, no issue tracker and none of this repo's
scripts, ...

Restore proven on both legs by blob-hash equality against the HEAD blob (779e4fec == 779e4fec, 26565625 == 26565625), marker count back to 0, and git diff HEAD empty. Every restore ran git checkout HEAD -- ABSOLUTE_PATH, never a bare git checkout --.

Verification

Gate union derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack at final HEAD 912a2715b5 on a clean tree — 35 runnable families (25 by path + 6 by change kind + 6 declared whole-tree, 2 reached both ways).

  • 33 of 35 green.
  • pnpm lint (the repo-wide eslint . --no-inline-config): 5855 files, 0 errors, 0 warnings, exit 0. Not narrowed.
  • pnpm --filter @objectstack/cli run typecheck: exit 0. check:test-typecheck holds at 3 files / 28 errors / 6 pinned signatures — the pre-existing ledger, unmoved; zero diagnostics in the edited file. Coverage proven positively: tsc -p packages/cli/tsconfig.test.json --noEmit --listFiles puts 1794 files in the program and the edited pin is among them (control: scaffold-manifest-schema.test.ts, also present). This matters because packages/cli's tsconfig.json is include: ["src"], so nothing else compiles test/.
  • pnpm --filter @objectstack/cli exec vitest run test/init-template-comments-self-contained.test.ts: 25 passed.

Two families NOT MEASURED — reported as NOT MEASURED, neither a pass nor a red:

  • pnpm check:dual-build-cjs-loadsexit 3, PREREQUISITE NOT MET: it reads built output and twelve packages have no dist/ in this worktree, which built only the @objectstack/cli dependency closure. Its own text: "This is NOT a pass: nothing was measured."
  • pnpm check:type-check-debtexit 124, killed by the 300s per-gate timeout. It needs the whole workspace closure built and re-runs tsc per ledger entry. Its relevant half is measured by other means above: the ledger a new test file in this package would move is packages/cli's, and check:test-typecheck holds it unchanged; check:type-check-coverage (the structural half) is green; this diff adds no package and touches no tsconfig.

Test scope narrowed, and the narrowing is measured rather than assumed: the diff is one file, it is a test file, and git grep finds no importer of it anywhere under packages/ (the single hit is a prose reference in another test's comment). No source changed, so the affected-test set is exactly the file that was run.

Changeset

None, and skip-changeset applies — measured from packages/cli's own manifest rather than asserted: its files field is ["dist","README.md","CHANGELOG.md"]. test/ is not among them, so a test-only diff under test/ publishes nothing and no user-visible change exists to describe.

Out of scope, filed not fixed

Per the card's fence, no comment this pin sweeps was edited. One finding came out of the sweep and is filed as #15150: assertion 1's MONOREPO_ONLY vocabulary has no pattern for a monorepo-relative path, so create's README.md linking ../../content/docs is swept and passes. Widening the vocabulary is a different review question from widening the population, and it carries a false-positive design problem the population change did not. The neighbouring instances (workspace:*, extends: '../../tsconfig.json') are already recorded as measured fact 1 of #14824, which remains open as the two-scaffolder decision; this PR is independent of its outcome, exactly as its triage said.

🤖 Generated with Claude Code

https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza


Generated by Claude Code

`init-template-comments-self-contained.test.ts` rendered its population from
one source — `TEMPLATES` from `init.js` — so its three assertions held for
`os init` only. `create.ts` exports a second, independent template map whose
entries render text straight into a scaffolded project, and nothing read it:
an edit to a `create` literal citing an ADR, or linking a docs page that later
moves, shipped to every `os create` user with every gate green.

The population is now DERIVED from both maps, the way
`scaffold-manifest-schema.test.ts` derives its own sweep, so a template added
to either map is swept the day it is added. `create` has no
`configContent`/`srcFiles` split, so every entry of its one `files` map is
rendered and serialised exactly the way `Create.run()` does.

The three assertions are reused unchanged; only their labels now name the
scaffold arm (`init:app`, `create:example`) so a failure says which command
ships the text. The `create` vacuity guard checks its in-source LITERALS were
reached rather than requiring an `objectstack.config.ts`, which its `plugin`
template deliberately does not emit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
@github-actions github-actions Bot added the size/m label Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 1876d5dfd8f309483ef424e7ddd69919409a06dcpackageMentionDocs.

@github-actions github-actions Bot added the tests label Sep 4, 2026
@os-trump os-trump added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed tests labels Sep 4, 2026 — with Claude
@os-trump
os-trump marked this pull request as ready for review September 4, 2026 03:42
@os-trump
os-trump enabled auto-merge September 4, 2026 03:42
@os-trump
os-trump added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit 25a59bd Sep 4, 2026
42 checks passed
@os-trump
os-trump deleted the claude/issue-14823-create-template-comments-pin branch September 4, 2026 04:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

init-template-comments-self-contained sweeps only os init's templates — the comments os create ships into a scaffolded project are unpinned

2 participants